package com.kfm.hotel.service.impl;

import com.anji.captcha.util.AESUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.kfm.hotel.domain.*;
import com.kfm.hotel.mapper.SysUserRoleMapper;
import com.kfm.hotel.service.SysMenuService;
import com.kfm.hotel.service.SysUserRoleService;
import com.kfm.hotel.service.SysUserService;
import com.kfm.hotel.mapper.SysUserMapper;
import com.kfm.hotel.util.MD5Util;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
* @author 10854
* @description 针对表【sys_user】的数据库操作Service实现
* @createDate 2023-05-29 15:22:24
*/
@Service
@Slf4j
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser>
    implements SysUserService{

    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysMenuService menuService;

    private static final String ROLE_PREFIX = "ROLE_";

    @Override
    public SysUser login(SysUser user) {
        // 密码 MD5 加密
        user.setPassword(MD5Util.MD5(user.getPassword(), user.getUsername()));
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.select("id", "username", "name", "phone", "create_time", "update_time", "state");
        wrapper.eq("username", user.getUsername());
        wrapper.eq("password", user.getPassword());
        wrapper.eq("state", 1);
        wrapper.eq("is_del", 0);
        SysUser one = getOne(wrapper);
        return one;
    }

    @Override
    public SysUser login(String username, String password) {
        SysUser user = new SysUser();
        user.setUsername(username);
        user.setPassword(password);
        return login(user);
    }

    @Override
    public int saveSysUser(SysUser user) {
        existUsername(user);

        // AES 解密
        String pass = "";
        try {
            pass = AESUtil.aesDecrypt(user.getPassword(), user.getKey());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 密码 MD5 加密
        user.setPassword(MD5Util.MD5(pass, user.getUsername()));
        return save(user) ? 1 : -1;
    }

    public void existUsername(SysUser user) {
        // 判断用户名是否存在, 只需要查询 count 数量即可
        QueryWrapper wrapper = new QueryWrapper<>();
        wrapper.select("count(1) as num");
        wrapper.eq("username", user.getUsername());
        wrapper.eq("is_del", 0);
        wrapper.eq("state", 1);
//        SysUser user1 = getOne(wrapper);

        Map<String, Long> map = getMap(wrapper);

        if (map.get("num") > 0){
            // new UsernameExtendsException("用户名已存在");
            throw new RuntimeException("用户名已存在");
        }
    }

    @Override
    @Transactional
    public void setUserRole(UserRoleDTO userRoleDTO) {
        // 把之前所有的用户角色信息删掉
        UpdateWrapper<SysUserRole> deleteWrapper = new UpdateWrapper<>();
        deleteWrapper.eq("user_id", userRoleDTO.getUserId());
        sysUserRoleService.remove(deleteWrapper);

        List<SysUserRole> list = new ArrayList<>();
        Integer[] roles = userRoleDTO.getRoles();

        for (int i = 0; i < roles.length; i ++){
            SysUserRole userRole = new SysUserRole();
            userRole.setUserId(userRoleDTO.getUserId());
            userRole.setRoleId(roles[i]);
            list.add(userRole);
        }

        sysUserRoleService.saveBatch(list);
    }

    @Override
    public Set<String> getPermission(Integer id) {
        List<SysMenu> menus = menuService.getAllMenusByUserId(id);
        Set<String> permissions = new HashSet<>();
        for (SysMenu menu : menus){
            if (menu.getPerms() != null && !menu.getPerms().equals("")){
                permissions.add(menu.getPerms());
            }
        }
        return permissions;
    }

    @Override
    public PageInfo<SysUser> list(SysUser user, Integer page, Integer limit) {
        // 分页
        PageHelper.startPage(page, limit);
        // 查询条件
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.select("id", "username", "name", "phone", "create_time", "update_time", "state");
        if (user.getUsername() != null && !user.getUsername().equals("")) {
            wrapper.like("username", user.getUsername());
        }
        wrapper.eq("state", 1);
        wrapper.eq("is_del", 0);

        // 查询并封装成 PageInfo 对象
        List<SysUser> sysUsers = getBaseMapper().listSelector(user);
        PageInfo<SysUser> pageInfo = new PageInfo<>(sysUsers);
        return pageInfo;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        log.info("自定义 UserDetailsService 加载用户信息");
        // 根据用户名查询用户信息
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);

        SysUser user = getOne(wrapper);

        if (user != null){
            // 查询用户的权限信息
            List<SysMenu> menus = menuService.getAllMenusByUserId(user.getId());
            // 查询用户的角色信息
            List<SysRole> roles = sysUserRoleService.getRoleByUserId(user.getId());


            Set<GrantedAuthority> authorities = new HashSet<>();
            // 添加角色
            for (SysRole role : roles){
                // 所有的角色都是 ROLE_ 开头
                authorities.add(new SimpleGrantedAuthority(ROLE_PREFIX + role.getMark().toUpperCase()));
            }
            for (SysMenu menu : menus){
                if (menu.getPerms() != null && !menu.getPerms().equals("")){
                    // 添加权限
                    authorities.add(new SimpleGrantedAuthority(menu.getPerms()));
                }
            }
            // 封装成 UserDetails 对象
            user.setAuthorities(authorities); // 添加权限

            return user;
        }

        return new SysUser();
    }
}




